// This is the main DLL file.

#include "stdafx.h"

#include "ScriptEnvironment.h"

namespace BlunderBrain{ namespace AviSynth{ namespace Interop{

	ScriptEnvironment::ScriptEnvironment()
	{
		m_scriptEnvironment = CreateScriptEnvironment();
		m_syncObj = gcnew Object();
	}

	ScriptEnvironment::~ScriptEnvironment()
	{
	}

	ScriptEnvironment::!ScriptEnvironment()
	{
		delete m_scriptEnvironment;
	}

	String^ ScriptEnvironment::GetVariable(String^ name)
	{
		System::Threading::Monitor::Enter(m_syncObj);
		String ^value = String::Empty;
		try
		{
			if(!String::IsNullOrEmpty(name))
			{
				IntPtr varName = Marshal::StringToCoTaskMemAnsi(name);

				try
				{
					AVSValue varValue = m_scriptEnvironment->GetVar((const char*)varName.ToPointer());

					if (varValue.IsString())
					{
						value = Marshal::PtrToStringAnsi((IntPtr)(char*)varValue.AsString());
					}
				}
				catch(IScriptEnvironment::NotFound)
				{
					value = String::Empty;
				}
				finally
				{
					Marshal::FreeCoTaskMem(varName);
				}
			}
		}
		finally
		{
			System::Threading::Monitor::Exit(m_syncObj);
		}
		return value;
	}

	IList<String^>^ ScriptEnvironment::GetInternalFunctions()
	{
		System::Threading::Monitor::Enter(m_syncObj);
		List<String^>^ functions = gcnew List<String^>();
		try
		{
			functions->AddRange(
				Linq::Enumerable::Distinct<String^>(
					this->GetVariable("$InternalFunctions$")->Split(gcnew array<Char>{' '}, StringSplitOptions::RemoveEmptyEntries)
						));
		}
		finally
		{
			System::Threading::Monitor::Exit(m_syncObj);
		}

		return functions;
	}

	IList<String^>^ ScriptEnvironment::GetPluginFunctions()
	{
		System::Threading::Monitor::Enter(m_syncObj);
		List<String^>^ functions = gcnew List<String^>();
	
		try
		{
			functions->AddRange(
				Linq::Enumerable::Distinct<String^>(
					this->GetVariable("$PluginFunctions$")->Split(gcnew array<Char>{' '}, StringSplitOptions::RemoveEmptyEntries)
					));
		}
		finally
		{
			System::Threading::Monitor::Exit(m_syncObj);
		}

		return functions;
	}

	String^ ScriptEnvironment::GetFunctionParameterSpec(String^ functionName)
	{
		return this->GetVariable(String::Format("$Plugin!{0}!Param$", functionName));
	}

}}}